#include "Oculus_RiftManager.h"

Oculus_RiftManager::Oculus_RiftManager()
{
	m_oculusReady = false;
	setup();
}

Oculus_RiftManager::~Oculus_RiftManager()
{
	shutdown();
}

bool Oculus_RiftManager::setup()
{
	try
	{
		if(m_oculusReady)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Already Initialised");
			return true;
		}
		Ogre::LogManager::getSingleton().logMessage("Oculus: Initialising system");
		OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All));
		m_deviceManager = OVR::DeviceManager::Create();
		if(!m_deviceManager)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create Device Manager");
			return false;
		}
		Ogre::LogManager::getSingleton().logMessage("Oculus: Created Device Manager");
		m_stereoConfig = new OVR::Util::Render::StereoConfig();
		if(!m_stereoConfig)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create StereoConfig");
			return false;
		}
		m_centreOffset = m_stereoConfig->GetProjectionCenterOffset();
		Ogre::LogManager::getSingleton().logMessage("Oculus: Created StereoConfig");
		m_hmd = m_deviceManager->EnumerateDevices<OVR::HMDDevice>().CreateDevice();
		if(!m_hmd)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create HMD");
			return false;
		}
		Ogre::LogManager::getSingleton().logMessage("Oculus: Created HMD");
		OVR::HMDInfo devinfo;
		m_hmd->GetDeviceInfo(&devinfo);
		m_stereoConfig->SetHMDInfo(devinfo);
		m_sensor = m_hmd->GetSensor();
		if(!m_sensor)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create sensor");
			return false;
		}
		Ogre::LogManager::getSingleton().logMessage("Oculus: Created sensor");
		m_sensorFusion = new OVR::SensorFusion();
		if(!m_sensorFusion)
		{
			Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create SensorFusion");
			return false;
		}
		Ogre::LogManager::getSingleton().logMessage("Oculus: Created SensorFusion");
		m_sensorFusion->AttachToSensor(m_sensor);
		m_oculusReady = true;
		Ogre::LogManager::getSingleton().logMessage("Oculus: Oculus setup completed successfully");
	}
	catch (...)
	{
		return false;
	}

	return true;
}

bool Oculus_RiftManager::shutdown()
{
	try
	{
		m_oculusReady = false;

		delete m_stereoConfig;
		m_stereoConfig = 0;
		delete m_sensorFusion;
		m_sensorFusion = 0;

		if(m_sensor)
		{
			m_sensor->Release();
		}
		if(m_hmd)
		{
			m_hmd->Release();
			m_hmd = 0;
		}
		if(m_deviceManager)
		{
			m_deviceManager->Release();
			m_deviceManager = 0;
		}

		OVR::System::Destroy();
	}
	catch (...)
	{
		return false;
	}

	return true;
}

Ogre::Quaternion Oculus_RiftManager::getOrientation() const
{
	if(m_oculusReady)
	{
		OVR::Quatf q = m_sensorFusion->GetOrientation();
		Ogre::Quaternion result(q.w,q.x,q.y,q.z);
		return result;
	}
	else
	{
		return Ogre::Quaternion::IDENTITY;
	}
}

void Oculus_RiftManager::reserOrientation()
{
	if(m_sensorFusion)
		m_sensorFusion->Reset();
}

OVR::Util::Render::StereoConfig* Oculus_RiftManager::getStereoConfig()
{
	return m_stereoConfig;
}